#include "Sockaddr.h"
#include "endian.h"
#include "sock.h"

#include <array>
#include <cstring>

Sockaddr::Sockaddr(uint16_t port, bool loopbackOnly): _addr{} {
    _addr.sin_family = AF_INET;
    _addr.sin_port = Endian::host_to_network(port);
    _addr.sin_addr.s_addr = Endian::host_to_network(loopbackOnly ? INADDR_LOOPBACK : INADDR_ANY);
}

Sockaddr::Sockaddr(const char *ip, uint16_t port) {
    Sock::IP_port_to_network(_addr, ip, port);
}


std::string Sockaddr::IP() const {
    std::array<char, 1 << 16> buffer{};
    Sock::network_to_IP(buffer.data(), buffer.size(), sock_addr());
    return buffer.data();
}

std::string Sockaddr::IP_port() const {
    std::array<char, 1 << 16> buffer{};
    Sock::network_to_IP_port(buffer.data(), buffer.size(), sock_addr());
    return buffer.data();
}

const struct sockaddr *Sockaddr::sock_addr() const {
    return Sock::sockaddr_cast(&_addr);
}
